# -*- coding: utf-8 -*-
"""
    xfree.core.auth.services
    ~~~~~~~~~~~~~~~~~~~~~
    文件描述：本模块提供了在xfree中用于认证和授权的服务。
    作者：xfree
    邮箱：cy_83k@qq.com
"""

from abc import ABC, abstractmethod

import attr


# 用户注册信息类，包含验证和创建新用户所需的所有相关信息
@attr.s(hash=True, eq=False, order=False, repr=True, frozen=True)
class UserRegistrationInfo(object):
    """
    用户注册对象，包含验证和创建新用户所需的所有相关信息。
    """

    username = attr.ib()  # 用户名
    password = attr.ib(repr=False)  # 密码（在表示时不显示）
    email = attr.ib()  # 电子邮件地址
    language = attr.ib()  # 用户选择的语言
    group = attr.ib()  # 用户所属的组


# 用户验证器，用于验证用户注册信息并通过抛出异常来停止注册过程
class UserValidator(ABC):
    """
    用于验证用户注册并通过抛出 :class:`~xfree.core.exceptions.ValidationError` 异常来停止注册过程。
    """

    @abstractmethod
    def validate(self, user_info):
        """
        此方法是抽象的。

        :param user_info: 提供的注册信息。
        :type user_info: :class:`~xfree.core.auth.registration.UserRegistrationInfo`
        """  # noqa

    def __call__(self, user_info):
        return self.validate(user_info)


# 注册失败处理器，用于处理注册过程中的失败情况
class RegistrationFailureHandler(ABC):
    """
    用于处理注册过程中的失败情况。
    """

    @abstractmethod
    def handle_failure(self, user_info, failures):
        """
        此方法是抽象的。

        :param user_info: 提供的注册信息。
        :param failures: 来自失败的（属性，消息）元组列表
        :type user_info: :class:`~xfree.core.auth.registration.UserRegistrationInfo`
        """  # noqa
        pass

    def __call__(self, user_info, failures):
        self.handle_failure(user_info, failures)


# 注册后处理器，用于在用户成功注册并持久化到数据库后进行后处理
class RegistrationPostProcessor(ABC):
    """
    用于在用户成功注册并持久化到数据库后进行后处理的接口。
    """

    @abstractmethod
    def post_process(self, user):
        """
        此方法是抽象的。

        :param user: 已注册并持久化的用户。
        :type user: :class:`~xfree.user.models.User`
        """
        pass

    def __call__(self, user):
        self.post_process(user)


# 用户注册服务，用于管理用户注册过程
class UserRegistrationService(ABC):
    """
    用于管理用户注册过程的接口。虽然提供了默认实现，但此接口可用于需要替代流程的情况。
    """

    @abstractmethod
    def register(self, user_info):
        """
        此方法是抽象的。

        :param user_info: 提供的用户注册信息。
        :type user_info: :class:`~xfree.core.auth.registration.UserRegistrationID`
        """  # noqa
        pass